/**
 * Copyright (C) 2010 DustedPixels.com
 */
package com.dustedpixels.cirt.awt;

import java.awt.image.BufferedImage;
import java.awt.image.DataBuffer;
import java.awt.image.DataBufferByte;
import java.awt.image.IndexColorModel;
import java.awt.image.PixelInterleavedSampleModel;
import java.awt.image.WritableRaster;
import java.util.Hashtable;

import com.google.common.base.Preconditions;

/**
 * VideoBufferedImage
 *
 * @author Michal Pociecha-Los (micapolos@gmail.com)
 */
public final class VideoImages {
  
  /**
   * Creates and returns new image, which is backed by a byte array with video
   * data, encoded using byte palette.
   * 
   * @param width image width
   * @param height image height
   * @param screenData image data bytes
   * @param redPalette palette of red components
   * @param greenPalette palette of green components
   * @param bluePalette palette of blue components
   * @return an image
   */
  public static BufferedImage newPaletteImage(
      final int width,
      final int height,
      final byte[] screenData,
      final byte[] redPalette,
      final byte[] greenPalette,
      final byte[] bluePalette) {
    Preconditions.checkArgument(width >= 0);
    Preconditions.checkArgument(height >= 0);
    Preconditions.checkNotNull(screenData);
    Preconditions.checkArgument(screenData.length >= width * height);
    Preconditions.checkNotNull(redPalette);
    Preconditions.checkNotNull(greenPalette);
    Preconditions.checkNotNull(bluePalette);
    Preconditions.checkArgument(redPalette.length == greenPalette.length);
    Preconditions.checkArgument(greenPalette.length == bluePalette.length);
    
    final int size = width * height;
    final int paletteSize = redPalette.length;

    // Create data buffer on top of screenData array
    DataBuffer dataBuffer = new DataBufferByte(screenData, size);
    
    // Create byte sample model, suitable for indexed color model
    PixelInterleavedSampleModel sampleModel = new PixelInterleavedSampleModel(
        DataBuffer.TYPE_BYTE,
        width,
        height,
        1,
        width,
        new int[] {0});
    
    // Create compatible raster, built on top dataBuffer and a sample model
    WritableRaster raster = WritableRaster.createInterleavedRaster(
        dataBuffer,
        width,
        height,
        sampleModel.getScanlineStride(),
        sampleModel.getPixelStride(),
        new int[] {0},  
        null);
    
    // Create indexed color model.
    IndexColorModel colorModel = new IndexColorModel(
        8, 
        paletteSize,
        redPalette,
        greenPalette,
        bluePalette);
    
    // Create buffered image on top of raster and color model
    @SuppressWarnings("unchecked")
    Hashtable bufferedImageProperties = new Hashtable();
    
    BufferedImage bufferedImage = new BufferedImage(
        colorModel,
        raster, 
        true, 
        bufferedImageProperties);
        
    return bufferedImage; 
  }
}
